<!DOCTYPE html>
<html lang="en" dir="ltr" class="client-nojs">
<head>
<title>PImpl - cppreference.com</title>
<meta charset="UTF-8">
<meta name="generator" content="MediaWiki 1.21.2">
<link rel="shortcut icon" href="../../../common/favicon.ico">
<link rel="stylesheet" href="../../../common/ext.css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" href="../../../common/site_modules.css">
<style>a:lang(ar),a:lang(ckb),a:lang(fa),a:lang(kk-arab),a:lang(mzn),a:lang(ps),a:lang(ur){text-decoration:none}#toc{display:none}.editsection{display:none}
/* cache key: mwiki1-mwiki_en_:resourceloader:filter:minify-css:7:472787eddcf4605d11de8c7ef047234f */</style>

<script src="../../../common/startup_scripts.js"></script>
<script>if(window.mw){
mw.config.set({"wgCanonicalNamespace":"","wgCanonicalSpecialPageName":false,"wgNamespaceNumber":0,"wgPageName":"cpp/language/pimpl","wgTitle":"cpp/language/pimpl","wgCurRevisionId":138246,"wgArticleId":14656,"wgIsArticle":true,"wgAction":"view","wgUserName":null,"wgUserGroups":["*"],"wgCategories":["Todo with reason"],"wgBreakFrames":false,"wgPageContentLanguage":"en","wgSeparatorTransformTable":["",""],"wgDigitTransformTable":["",""],"wgDefaultDateFormat":"dmy","wgMonthNames":["","January","February","March","April","May","June","July","August","September","October","November","December"],"wgMonthNamesShort":["","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"wgRelevantPageName":"cpp/language/pimpl","wgRestrictionEdit":[],"wgRestrictionMove":[]});
}</script><script>if(window.mw){
mw.loader.implement("user.options",function(){mw.user.options.set({"ccmeonemails":0,"cols":80,"date":"default","diffonly":0,"disablemail":0,"disablesuggest":0,"editfont":"default","editondblclick":0,"editsection":0,"editsectiononrightclick":0,"enotifminoredits":0,"enotifrevealaddr":0,"enotifusertalkpages":1,"enotifwatchlistpages":0,"extendwatchlist":0,"externaldiff":0,"externaleditor":0,"fancysig":0,"forceeditsummary":0,"gender":"unknown","hideminor":0,"hidepatrolled":0,"imagesize":2,"justify":0,"math":1,"minordefault":0,"newpageshidepatrolled":0,"nocache":0,"noconvertlink":0,"norollbackdiff":0,"numberheadings":0,"previewonfirst":0,"previewontop":1,"quickbar":5,"rcdays":7,"rclimit":50,"rememberpassword":0,"rows":25,"searchlimit":20,"showhiddencats":0,"showjumplinks":1,"shownumberswatching":1,"showtoc":0,"showtoolbar":1,"skin":"cppreference2","stubthreshold":0,"thumbsize":2,"underline":2,"uselivepreview":0,"usenewrc":0,"watchcreations":0,"watchdefault":0,"watchdeletion":0,
"watchlistdays":3,"watchlisthideanons":0,"watchlisthidebots":0,"watchlisthideliu":0,"watchlisthideminor":0,"watchlisthideown":0,"watchlisthidepatrolled":0,"watchmoves":0,"wllimit":250,"variant":"en","language":"en","searchNs0":true,"searchNs1":false,"searchNs2":false,"searchNs3":false,"searchNs4":false,"searchNs5":false,"searchNs6":false,"searchNs7":false,"searchNs8":false,"searchNs9":false,"searchNs10":false,"searchNs11":false,"searchNs12":false,"searchNs13":false,"searchNs14":false,"searchNs15":false,"gadget-ColiruCompiler":1,"gadget-MathJax":1});;},{},{});mw.loader.implement("user.tokens",function(){mw.user.tokens.set({"editToken":"+\\","patrolToken":false,"watchToken":false});;},{},{});
/* cache key: mwiki1-mwiki_en_:resourceloader:filter:minify-js:7:9f05c6caceb9bb1a482b6cebd4c5a330 */
}</script>
<script>if(window.mw){
mw.loader.load(["mediawiki.page.startup","mediawiki.legacy.wikibits","mediawiki.legacy.ajax"]);
}</script>
<style type="text/css">/*<![CDATA[*/
.source-cpp {line-height: normal;}
.source-cpp li, .source-cpp pre {
	line-height: normal; border: 0px none white;
}
/**
 * GeSHi Dynamically Generated Stylesheet
 * --------------------------------------
 * Dynamically generated stylesheet for cpp
 * CSS class: source-cpp, CSS id: 
 * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
 * (http://qbnz.com/highlighter/ and http://geshi.org/)
 * --------------------------------------
 */
.cpp.source-cpp .de1, .cpp.source-cpp .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
.cpp.source-cpp  {font-family:monospace;}
.cpp.source-cpp .imp {font-weight: bold; color: red;}
.cpp.source-cpp li, .cpp.source-cpp .li1 {font-weight: normal; vertical-align:top;}
.cpp.source-cpp .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
.cpp.source-cpp .li2 {font-weight: bold; vertical-align:top;}
.cpp.source-cpp .kw1 {color: #0000dd;}
.cpp.source-cpp .kw2 {color: #0000ff;}
.cpp.source-cpp .kw3 {color: #0000dd;}
.cpp.source-cpp .kw4 {color: #0000ff;}
.cpp.source-cpp .co1 {color: #909090;}
.cpp.source-cpp .co2 {color: #339900;}
.cpp.source-cpp .coMULTI {color: #ff0000; font-style: italic;}
.cpp.source-cpp .es0 {color: #008000; font-weight: bold;}
.cpp.source-cpp .es1 {color: #008000; font-weight: bold;}
.cpp.source-cpp .es2 {color: #008000; font-weight: bold;}
.cpp.source-cpp .es3 {color: #008000; font-weight: bold;}
.cpp.source-cpp .es4 {color: #008000; font-weight: bold;}
.cpp.source-cpp .es5 {color: #008000; font-weight: bold;}
.cpp.source-cpp .br0 {color: #008000;}
.cpp.source-cpp .sy0 {color: #008000;}
.cpp.source-cpp .sy1 {color: #000080;}
.cpp.source-cpp .sy2 {color: #000040;}
.cpp.source-cpp .sy3 {color: #000040;}
.cpp.source-cpp .sy4 {color: #008080;}
.cpp.source-cpp .st0 {color: #008000;}
.cpp.source-cpp .nu0 {color: #000080;}
.cpp.source-cpp .nu6 {color: #000080;}
.cpp.source-cpp .nu8 {color: #000080;}
.cpp.source-cpp .nu12 {color: #000080;}
.cpp.source-cpp .nu16 {color:#000080;}
.cpp.source-cpp .nu17 {color:#000080;}
.cpp.source-cpp .nu18 {color:#000080;}
.cpp.source-cpp .nu19 {color:#000080;}
.cpp.source-cpp .ln-xtra, .cpp.source-cpp li.ln-xtra, .cpp.source-cpp div.ln-xtra {background-color: #ffc;}
.cpp.source-cpp span.xtra { display:block; }

/*]]>*/
</style><style type="text/css">/*<![CDATA[*/
.source-text {line-height: normal;}
.source-text li, .source-text pre {
	line-height: normal; border: 0px none white;
}
/**
 * GeSHi Dynamically Generated Stylesheet
 * --------------------------------------
 * Dynamically generated stylesheet for text
 * CSS class: source-text, CSS id: 
 * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
 * (http://qbnz.com/highlighter/ and http://geshi.org/)
 * --------------------------------------
 */
.text.source-text .de1, .text.source-text .de2 {font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;}
.text.source-text  {font-family:monospace;}
.text.source-text .imp {font-weight: bold; color: red;}
.text.source-text li, .text.source-text .li1 {font-weight: normal; vertical-align:top;}
.text.source-text .ln {width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;}
.text.source-text .li2 {font-weight: bold; vertical-align:top;}
.text.source-text .ln-xtra, .text.source-text li.ln-xtra, .text.source-text div.ln-xtra {background-color: #ffc;}
.text.source-text span.xtra { display:block; }

/*]]>*/
</style><!--[if lt IE 7]><style type="text/css">body{behavior:url("/mwiki/skins/cppreference2/csshover.min.htc")}</style><![endif]--></head>
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-cpp_language_pimpl skin-cppreference2 action-view cpp-navbar">
        <!-- header -->
        <!-- /header -->
        <!-- content -->
<div id="cpp-content-base">
            <div id="content">
                <a id="top"></a>
                <div id="mw-js-message" style="display:none;"></div>
                                <!-- firstHeading -->
<h1 id="firstHeading" class="firstHeading">PImpl</h1>
                <!-- /firstHeading -->
                <!-- bodyContent -->
                <div id="bodyContent">
                                        <!-- tagline -->
                    <div id="siteSub">From cppreference.com</div>
                    <!-- /tagline -->
                                        <!-- subtitle -->
                    <div id="contentSub"><span class="subpages">&lt; <a href="../../cpp.html" title="cpp">cpp</a>‎ | <a href="../language.html" title="cpp/language">language</a></span></div>
                    <!-- /subtitle -->
                                                            <!-- bodycontent -->
                    <div id="mw-content-text" lang="en" dir="ltr" class="mw-content-ltr"><div class="t-navbar" style=""><div class="t-navbar-sep"> </div><div class="t-navbar-head"><a href="../../cpp.html" title="cpp"> C++</a><div class="t-navbar-menu"><div><div><table class="t-nv-begin" cellpadding="0" style="line-height:1.1em;">
<tr class="t-nv"><td colspan="5"> <a href="../compiler_support.html" title="cpp/compiler support"> Compiler support</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../freestanding.html" title="cpp/freestanding"> Freestanding and hosted</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../language.html" title="cpp/language"> Language</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../header.html" title="cpp/header"> Standard library headers</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../named_req.html" title="cpp/named req"> Named requirements </a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../feature_test.html" title="cpp/feature test"> Feature test macros </a> <span class="t-mark-rev t-since-cxx20">(C++20)</span> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../utility.html#Language_support" title="cpp/utility"> Language support library</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../concepts.html" title="cpp/concepts"> Concepts library</a> <span class="t-mark-rev t-since-cxx20">(C++20)</span> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../meta.html" title="cpp/meta"> Metaprogramming library</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../error.html" title="cpp/error"> Diagnostics library</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../utility.html" title="cpp/utility"> General utilities library</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../string.html" title="cpp/string"> Strings library</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../container.html" title="cpp/container"> Containers library</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../iterator.html" title="cpp/iterator"> Iterators library</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../ranges.html" title="cpp/ranges"> Ranges library</a> <span class="t-mark-rev t-since-cxx20">(C++20)</span> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../algorithm.html" title="cpp/algorithm"> Algorithms library</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../numeric.html" title="cpp/numeric"> Numerics library</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../locale.html" title="cpp/locale"> Localizations library</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../io.html" title="cpp/io"> Input/output library</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../filesystem.html" title="cpp/filesystem"> Filesystem library</a> <span class="t-mark-rev t-since-cxx17">(C++17)</span> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../regex.html" title="cpp/regex"> Regular expressions library</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../thread.html" title="cpp/thread"> Concurrency support library</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../experimental.html" title="cpp/experimental"> Technical specifications</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../symbol_index.html" title="cpp/symbol index"> Symbols index</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../links/libs.html" title="cpp/links/libs"> External libraries</a> </td></tr>
</table></div><div></div></div></div></div><div class="t-navbar-sep"> </div><div class="t-navbar-head"><a href="../language.html" title="cpp/language"> C++ language</a><div class="t-navbar-menu"><div><div style="display:inline-block">
<div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv-h1"><td colspan="5"> General topics</td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="../preprocessor.html" title="cpp/preprocessor"> Preprocessor</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="../comments.html" title="cpp/comment"> Comments</a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="../keywords.html" title="cpp/keyword"> Keywords</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="escape.html" title="cpp/language/escape"> Escape sequences</a></td></tr>
</table></div></td></tr>
<tr class="t-nv-h1"><td colspan="5"> <a href="statements.html" title="cpp/language/statements"> Flow control</a></td></tr>
<tr class="t-nv-h2"><td colspan="5"> Conditional execution statements</td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="if.html" title="cpp/language/if"><tt>if</tt></a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="switch.html" title="cpp/language/switch"><tt>switch</tt></a></td></tr>
</table></div></td></tr>
<tr class="t-nv-h2"><td colspan="5"> Iteration statements (loops)</td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="for.html" title="cpp/language/for"><tt>for</tt></a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="range-for.html" title="cpp/language/range-for"> range-<code>for</code></a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="while.html" title="cpp/language/while"><tt>while</tt></a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="do.html" title="cpp/language/do"> <code>do-while</code></a></td></tr>
</table></div></td></tr>
<tr class="t-nv-h2"><td colspan="5"> Jump statements </td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="continue.html" title="cpp/language/continue"><tt>continue</tt></a> - <a href="break.html" title="cpp/language/break"><tt>break</tt></a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="goto.html" title="cpp/language/goto"><tt>goto</tt></a> - <a href="return.html" title="cpp/language/return"><tt>return</tt></a></td></tr>
</table></div></td></tr>
<tr class="t-nv-h1"><td colspan="5"> <a href="functions.html" title="cpp/language/functions"> Functions</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="function.html" title="cpp/language/function"> Function declaration</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="lambda.html" title="cpp/language/lambda"> Lambda function expression</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="inline.html" title="cpp/language/inline"> <code>inline</code> specifier</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="except_spec.html" title="cpp/language/except spec"> Dynamic exception specifications</a> <span class="t-mark-rev t-until-cxx20">(until C++20)</span></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="noexcept_spec.html" title="cpp/language/noexcept spec"> <code>noexcept</code> specifier</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
<tr class="t-nv-h1"><td colspan="5"> Exceptions</td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="throw.html" title="cpp/language/throw"> <code>throw</code>-expression</a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="try_catch.html" title="cpp/language/try catch"> <code>try</code>-<code>catch</code> block</a></td></tr>
</table></div></td></tr>
<tr class="t-nv-h1"><td colspan="5"> Namespaces</td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="namespace.html" title="cpp/language/namespace"> Namespace declaration</a>  </td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="namespace_alias.html" title="cpp/language/namespace alias"> Namespace aliases</a></td></tr>
</table></div></td></tr>
<tr class="t-nv-h1"><td colspan="5"> Types</td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="types.html" title="cpp/language/types"> Fundamental types</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="enum_class.html" title="cpp/language/enum"> Enumeration types</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="function.html" title="cpp/language/function"> Function types</a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="class.html" title="cpp/language/class"> Class/struct types</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="union.html" title="cpp/language/union"> Union types</a></td></tr>
</table></div></td></tr>
<tr class="t-nv-h2"><td colspan="5"> Specifiers</td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="decltype.html" title="cpp/language/decltype"><tt>decltype</tt></a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="auto.html" title="cpp/language/auto"><tt>auto</tt></a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="alignas.html" title="cpp/language/alignas"><tt>alignas</tt></a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="cv.html" title="cpp/language/cv"> <code>const</code>/<code>volatile</code></a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="constexpr.html" title="cpp/language/constexpr"><tt>constexpr</tt></a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
</table></div></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="storage_duration.html" title="cpp/language/storage duration"> Storage duration specifiers</a></td></tr>
<tr class="t-nv-h2"><td colspan="5"> <a href="initialization.html" title="cpp/language/initialization"> Initialization</a></td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="default_initialization.html" title="cpp/language/default initialization"> Default initialization</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="value_initialization.html" title="cpp/language/value initialization"> Value initialization</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="zero_initialization.html" title="cpp/language/zero initialization"> Zero initialization</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="copy_initialization.html" title="cpp/language/copy initialization"> Copy initialization</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="direct_initialization.html" title="cpp/language/direct initialization"> Direct initialization</a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="aggregate_initialization.html" title="cpp/language/aggregate initialization"> Aggregate initialization</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="list_initialization.html" title="cpp/language/list initialization"> List initialization</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="constant_initialization.html" title="cpp/language/constant initialization"> Constant initialization</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="reference_initialization.html" title="cpp/language/reference initialization"> Reference initialization</a></td></tr>
</table></div></td></tr>
</table></div>
</div>
<div style="display:inline-block">
<div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv-h1"><td colspan="5"> <a href="expressions.html" title="cpp/language/expressions"> Expressions</a></td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="value_category.html" title="cpp/language/value category"> Value categories</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="eval_order.html" title="cpp/language/eval order"> Order of evaluation</a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="operators.html" title="cpp/language/operators"> Operators</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="operator_precedence.html" title="cpp/language/operator precedence"> Operator precedence</a></td></tr>
</table></div></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="operator_alternative.html" title="cpp/language/operator alternative"> Alternative representations</a></td></tr>
<tr class="t-nv-h2"><td colspan="5"> <a href="expressions.html#Literals" title="cpp/language/expressions"> Literals</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="bool_literal.html" title="cpp/language/bool literal"> Boolean</a> - <a href="integer_literal.html" title="cpp/language/integer literal"> Integer</a> - <a href="floating_literal.html" title="cpp/language/floating literal"> Floating-point</a></td></tr>   
<tr class="t-nv"><td colspan="5"> <a href="character_literal.html" title="cpp/language/character literal"> Character</a> - <a href="string_literal.html" title="cpp/language/string literal"> String</a> - <a href="nullptr.html" title="cpp/language/nullptr"><tt>nullptr</tt></a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr> 
<tr class="t-nv"><td colspan="5"> <a href="user_literal.html" title="cpp/language/user literal"> User-defined</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
<tr class="t-nv-h1"><td colspan="5"> Utilities</td></tr>
<tr class="t-nv"><td colspan="5"> <a href="attributes.html" title="cpp/language/attributes"> Attributes</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
<tr class="t-nv-h2"><td colspan="5"> Types</td></tr>
<tr class="t-nv"><td colspan="5"> <a href="typedef.html" title="cpp/language/typedef"> <code>typedef</code> declaration</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="type_alias.html" title="cpp/language/type alias"> Type alias declaration</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
<tr class="t-nv-h2"><td colspan="5"> Casts</td></tr>
<tr class="t-nv"><td colspan="5"> <a href="implicit_cast.html" title="cpp/language/implicit conversion"> Implicit conversions</a> - <a href="explicit_cast.html" title="cpp/language/explicit cast"> Explicit conversions</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="static_cast.html" title="cpp/language/static cast"><tt>static_cast</tt></a> - <a href="dynamic_cast.html" title="cpp/language/dynamic cast"><tt>dynamic_cast</tt></a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="const_cast.html" title="cpp/language/const cast"><tt>const_cast</tt></a> - <a href="reinterpret_cast.html" title="cpp/language/reinterpret cast"><tt>reinterpret_cast</tt></a></td></tr>
<tr class="t-nv-h2"><td colspan="5"> Memory allocation</td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="new.html" title="cpp/language/new"> <code>new</code> expression</a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="delete.html" title="cpp/language/delete"> <code>delete</code> expression</a></td></tr>
</table></div></td></tr>
<tr class="t-nv-h1"><td colspan="5"> <a href="classes.html" title="cpp/language/classes"> Classes</a></td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="class.html" title="cpp/language/class"> Class declaration</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="initializer_list.html" title="cpp/language/constructor"> Constructors</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="this.html" title="cpp/language/this"> <code>this</code> pointer</a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="access.html" title="cpp/language/access"> Access specifiers</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="friend.html" title="cpp/language/friend"> <code>friend</code> specifier</a></td></tr>
</table></div></td></tr>
<tr class="t-nv-h2"><td colspan="5"> Class-specific function properties</td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="virtual.html" title="cpp/language/virtual"> Virtual function</a> </td></tr>
<tr class="t-nv"><td colspan="5"> <a href="override.html" title="cpp/language/override"> <code>override</code> specifier</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="final.html" title="cpp/language/final"> <code>final</code> specifier</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="explicit.html" title="cpp/language/explicit"><tt>explicit</tt></a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="static.html" title="cpp/language/static"><tt>static</tt></a> </td></tr>
</table></div></td></tr>
<tr class="t-nv-h2"><td colspan="5"> Special member functions</td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="default_constructor.html" title="cpp/language/default constructor"> Default constructor</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="copy_constructor.html" title="cpp/language/copy constructor"> Copy constructor</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="move_constructor.html" title="cpp/language/move constructor"> Move constructor</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="as_operator.html" title="cpp/language/as operator" class="mw-redirect"> Copy assignment</a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="move_operator.html" title="cpp/language/move operator" class="mw-redirect"> Move assignment</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="destructor.html" title="cpp/language/destructor"> Destructor</a></td></tr>
</table></div></td></tr>
<tr class="t-nv-h1"><td colspan="5"><a href="templates.html" title="cpp/language/templates"> Templates</a> </td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="class_template.html" title="cpp/language/class template"> Class template </a></td></tr>
<tr class="t-nv"><td colspan="5"> <a href="function_template.html" title="cpp/language/function template"> Function template </a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="template_specialization.html" title="cpp/language/template specialization"> Template specialization</a></td></tr>   
<tr class="t-nv"><td colspan="5"> <a href="parameter_pack.html" title="cpp/language/parameter pack"> Parameter packs</a> <span class="t-mark-rev t-since-cxx11">(C++11)</span></td></tr>
</table></div></td></tr>
<tr class="t-nv-h1"><td colspan="5"> Miscellaneous </td></tr>
<tr class="t-nv-col-table"><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="asm.html" title="cpp/language/asm"> Inline assembly</a></td></tr>
</table></div></td><td><div><table class="t-nv-begin" cellpadding="0" style="">
<tr class="t-nv"><td colspan="5"> <a href="history.html" title="cpp/language/history"> History of C++</a></td></tr>
</table></div></td></tr>
</table></div>
</div><div></div></div></div></div><div class="t-navbar-sep"> </div></div>
<p>"Pointer to implementation" or "pImpl" is a C++ programming technique<sup id="cite_ref-1" class="reference"><a href="pimpl.html#cite_note-1">[1]</a></sup> that removes implementation details of a class from its object representation by placing them in a separate class, accessed through an opaque pointer:
</p>
<div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="cpp source-cpp"><pre class="de1"><span class="co1">// --------------------</span>
<span class="co1">// interface (widget.h)</span>
<span class="kw1">class</span> widget
<span class="br0">{</span>
    <span class="co1">// public members</span>
<span class="kw1">private</span><span class="sy4">:</span>
    <span class="kw1">struct</span> impl<span class="sy4">;</span> <span class="co1">// forward declaration of the implementation class</span>
    <span class="co1">// One implementation example: see below for other design options and trade-offs</span>
    <a href="../experimental/propagate_const.html"><span class="kw2427">std::<span class="me2">experimental</span><span class="sy4">::</span><span class="me2">propagate_const</span></span></a><span class="sy1">&lt;</span> <span class="co1">// const-forwarding pointer wrapper</span>
        <a href="../memory/unique_ptr.html"><span class="kw734">std::<span class="me2">unique_ptr</span></span></a><span class="sy1">&lt;</span>                <span class="co1">// unique-ownership opaque pointer</span>
            impl<span class="sy1">&gt;&gt;</span> pImpl<span class="sy4">;</span>               <span class="co1">// to the forward-declared implementation class</span>
<span class="br0">}</span><span class="sy4">;</span>
 
<span class="co1">// ---------------------------</span>
<span class="co1">// implementation (widget.cpp)</span>
<span class="kw1">struct</span> widget<span class="sy4">::</span><span class="me2">impl</span>
<span class="br0">{</span>
    <span class="co1">// implementation details</span>
<span class="br0">}</span><span class="sy4">;</span></pre></div></div>
<p>This technique is used to construct C++ library interfaces with stable ABI and to reduce compile-time dependencies.
</p>
<h3><span class="mw-headline" id="Explanation">Explanation</span></h3>
<p>Because private data members of a class participate in its object representation, affecting size and layout, and because private member functions of a class participate in <a href="overload_resolution.html" title="cpp/language/overload resolution">overload resolution</a> (which takes place before member access checking), any change to those implementation details requires recompilation of all users of the class.
</p><p>pImpl removes this compilation dependency; changes to the implementation do not cause recompilation. Consequently, if a library uses pImpl in its ABI, newer versions of the library may change the implementation while remaining ABI-compatible with older versions.
</p>
<h3><span class="mw-headline" id="Trade-offs">Trade-offs</span></h3>
<p>The alternatives to the pImpl idiom are
</p>
<ul><li> inline implementation: private members and public members are members of the same class
</li><li> pure abstract class (OOP factory): users obtain a unique pointer to a lightweight or abstract base class, the implementation details are in the derived class that overrides its virtual member functions
</li></ul>
<h4><span class="mw-headline" id="Compilation_firewall">Compilation firewall</span></h4>
<p>In simple cases, both pImpl and factory method remove compile-time dependency between the implementation and the users of the class interface. Factory method creates a hidden dependency on the vtable, and so reordering, adding, or removing virtual member functions breaks the ABI. The pImpl approach has no hidden dependencies, however if the implementation class is a class template specialization, the compilation firewall benefit is lost: the users of the interface must observe the entire template definition in order to instantiate the correct specialization. A common design approach in this case is to refactor the implementation in a way that avoids parametrization, this is another use case for the C++ Core Guidelines:
</p>
<ul><li> <a rel="nofollow" class="external text" href="https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rt-scary">T.61 Do not over-parametrize members</a> and
</li><li> <a rel="nofollow" class="external text" href="https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#t84-use-a-non-template-core-implementation-to-provide-an-abi-stable-interface">T.84 Use a non-template core implementation to provide an ABI-stable interface</a>
</li></ul>
<p>For example, the following class template does not use the type <code>T</code> in its private member or in the body of <code>push_back</code>: 
</p>
<div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="cpp source-cpp"><pre class="de1"><span class="kw1">template</span><span class="sy1">&lt;</span><span class="kw1">class</span> T<span class="sy1">&gt;</span>
<span class="kw1">class</span> ptr_vector
<span class="br0">{</span>
    <a href="../container/vector.html"><span class="kw1272">std::<span class="me2">vector</span></span></a><span class="sy1">&lt;</span><span class="kw4">void</span><span class="sy2">*</span><span class="sy1">&gt;</span> vp<span class="sy4">;</span>
 
<span class="kw1">public</span><span class="sy4">:</span>
    <span class="kw4">void</span> push_back<span class="br0">(</span>T<span class="sy2">*</span> p<span class="br0">)</span>
    <span class="br0">{</span>
        vp.<span class="me1">push_back</span><span class="br0">(</span>p<span class="br0">)</span><span class="sy4">;</span>
    <span class="br0">}</span>
<span class="br0">}</span><span class="sy4">;</span></pre></div></div>
<p>Therefore, private members can be transferred to implementation as-is, and <code>push_back</code> can forward to an implementation that does not use <code>T</code> in the interface either:
</p>
<div class="t-example"><div class="t-example-live-link"><div class="coliru-btn coliru-btn-run-init">Run this code</div></div>
<div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="cpp source-cpp"><pre class="de1"><span class="co1">// ---------------------</span>
<span class="co1">// header (ptr_vector.hpp)</span>
<span class="co2">#include &lt;memory&gt;</span>
<span class="kw1">class</span> ptr_vector_base
<span class="br0">{</span>
    <span class="kw1">struct</span> impl<span class="sy4">;</span> <span class="co1">// does not depend on T</span>
    <a href="../memory/unique_ptr.html"><span class="kw734">std::<span class="me2">unique_ptr</span></span></a><span class="sy1">&lt;</span>impl<span class="sy1">&gt;</span> pImpl<span class="sy4">;</span>
<span class="kw1">protected</span><span class="sy4">:</span>
    <span class="kw4">void</span> push_back_fwd<span class="br0">(</span><span class="kw4">void</span><span class="sy2">*</span><span class="br0">)</span><span class="sy4">;</span>
    <span class="kw4">void</span> print<span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span><span class="sy4">;</span>
    <span class="co1">// ... see implementation section for special member functions</span>
<span class="kw1">public</span><span class="sy4">:</span>
    ptr_vector_base<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
    ~ptr_vector_base<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
<span class="br0">}</span><span class="sy4">;</span>
 
<span class="kw1">template</span><span class="sy1">&lt;</span><span class="kw1">class</span> T<span class="sy1">&gt;</span>
<span class="kw1">class</span> ptr_vector <span class="sy4">:</span> <span class="kw1">private</span> ptr_vector_base
<span class="br0">{</span>
<span class="kw1">public</span><span class="sy4">:</span>
    <span class="kw4">void</span> push_back<span class="br0">(</span>T<span class="sy2">*</span> p<span class="br0">)</span> <span class="br0">{</span> push_back_fwd<span class="br0">(</span>p<span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
    <span class="kw4">void</span> print<span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span> <span class="br0">{</span> ptr_vector_base<span class="sy4">::</span><span class="me2">print</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
<span class="br0">}</span><span class="sy4">;</span>
 
<span class="co1">// -----------------------</span>
<span class="co1">// source (ptr_vector.cpp)</span>
<span class="co1">// #include "ptr_vector.hpp"</span>
<span class="co2">#include &lt;vector&gt;</span>
<span class="co2">#include &lt;iostream&gt;</span>
<span class="kw1">struct</span> ptr_vector_base<span class="sy4">::</span><span class="me2">impl</span>
<span class="br0">{</span>
    <a href="../container/vector.html"><span class="kw1272">std::<span class="me2">vector</span></span></a><span class="sy1">&lt;</span><span class="kw4">void</span><span class="sy2">*</span><span class="sy1">&gt;</span> vp<span class="sy4">;</span>
 
    <span class="kw4">void</span> push_back<span class="br0">(</span><span class="kw4">void</span><span class="sy2">*</span> p<span class="br0">)</span>
    <span class="br0">{</span>
        vp.<span class="me1">push_back</span><span class="br0">(</span>p<span class="br0">)</span><span class="sy4">;</span>
    <span class="br0">}</span>
 
    <span class="kw4">void</span> print<span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span>
    <span class="br0">{</span>
        <span class="kw1">for</span> <span class="br0">(</span><span class="kw4">void</span> <span class="kw4">const</span> <span class="sy2">*</span> <span class="kw4">const</span> p<span class="sy4">:</span> vp<span class="br0">)</span> <a href="../io/cout.html"><span class="kw1762">std::<span class="me2">cout</span></span></a> <span class="sy1">&lt;&lt;</span> p <span class="sy1">&lt;&lt;</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
    <span class="br0">}</span>
<span class="br0">}</span><span class="sy4">;</span>
 
<span class="kw4">void</span> ptr_vector_base<span class="sy4">::</span><span class="me2">push_back_fwd</span><span class="br0">(</span><span class="kw4">void</span><span class="sy2">*</span> p<span class="br0">)</span> <span class="br0">{</span> pImpl<span class="sy2">-</span><span class="sy1">&gt;</span>push_back<span class="br0">(</span>p<span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
ptr_vector_base<span class="sy4">::</span><span class="me2">ptr_vector_base</span><span class="br0">(</span><span class="br0">)</span> <span class="sy4">:</span> pImpl<span class="br0">{</span><a href="../memory/unique_ptr/make_unique.html"><span class="kw736">std::<span class="me2">make_unique</span></span></a><span class="sy1">&lt;</span>impl<span class="sy1">&gt;</span><span class="br0">(</span><span class="br0">)</span><span class="br0">}</span> <span class="br0">{</span><span class="br0">}</span>
ptr_vector_base<span class="sy4">::</span>~ptr_vector_base<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
<span class="kw4">void</span> ptr_vector_base<span class="sy4">::</span><span class="me2">print</span><span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span> <span class="br0">{</span> pImpl<span class="sy2">-</span><span class="sy1">&gt;</span>print<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
 
<span class="co1">// ---------------</span>
<span class="co1">// user (main.cpp)</span>
<span class="co1">// #include "ptr_vector.hpp"</span>
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
<span class="br0">{</span>
    <span class="kw4">int</span> x<span class="br0">{</span><span class="br0">}</span>, y<span class="br0">{</span><span class="br0">}</span>, z<span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
    ptr_vector<span class="sy1">&lt;</span><span class="kw4">int</span><span class="sy1">&gt;</span> v<span class="sy4">;</span>
    v.<span class="me1">push_back</span><span class="br0">(</span><span class="sy3">&amp;</span>x<span class="br0">)</span><span class="sy4">;</span>
    v.<span class="me1">push_back</span><span class="br0">(</span><span class="sy3">&amp;</span>y<span class="br0">)</span><span class="sy4">;</span>
    v.<span class="me1">push_back</span><span class="br0">(</span><span class="sy3">&amp;</span>z<span class="br0">)</span><span class="sy4">;</span>
    v.<span class="me1">print</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
<span class="br0">}</span></pre></div></div>
<p>Possible output:
</p>
<div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="text source-text"><pre class="de1">0x7ffd6200a42c
0x7ffd6200a430
0x7ffd6200a434</pre></div></div> 
</div>
<h4><span class="mw-headline" id="Runtime_overhead">Runtime overhead</span></h4>
<ul><li> Access overhead: In pImpl, each call to a private member function indirects through a pointer. Each access to a public member made by a private member indirects through another pointer. Both indirections cross translation unit boundaries and so can only be optimized out by link-time optimization. Note that OO factory requires indirection across translation units to access both public data and implementation detail, and offers even fewer opportunities for the link time optimizer due to virtual dispatch.
</li><li> Space overhead: pImpl adds one pointer to the public component and, if any private member needs access to a public member, another pointer is either added to the implementation component or passed as a parameter for each call to the private member that requires it. If stateful custom allocators are supported, the allocator instance also has to be stored.
</li><li> Lifetime management overhead: pImpl (as well as OO factory) place the implementation object on the heap, which imposes significant runtime overhead at construction and destruction. This may be partially offset by custom allocators, since allocation size for pImpl (but not OO factory) is known at compile time.
</li></ul>
<p>On the other hand, pImpl classes are move-friendly; refactoring a large class as movable pImpl may improve performance of algorithms that manipulate containers holding such objects, although movable pImpl has an additional source of runtime overhead: any public member function that is permitted on a moved-from object and needs access to private implementation incurs a null pointer check.
</p>
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style=""><tr><td class="mbox-empty-cell"></td><td class="mbox-text" style="">This section is incomplete<br>Reason: Microbenchmark?) </td></tr></table>
<h4><span class="mw-headline" id="Maintenance_overhead">Maintenance overhead</span></h4>
<p>Use of pImpl requires a dedicated translation unit (a header-only library cannot use pImpl), introduces an additional class, a set of forwarding functions, and, if allocators are used, exposes the implementation detail of allocator use in the public interface.
</p><p>Since virtual members are part of the interface component of pImpl, mocking a pImpl implies mocking the interface component alone. A testable pImpl is typically designed to allow full test coverage through the available interface.
</p>
<h3><span class="mw-headline" id="Implementation">Implementation</span></h3>
<p>As the object of the interface type controls the lifetime of the object of the implementation type, the pointer to implementation is usually <span class="t-lc"><a href="../memory/unique_ptr.html" title="cpp/memory/unique ptr">std::unique_ptr</a></span>.
</p><p>Because <span class="t-lc"><a href="../memory/unique_ptr.html" title="cpp/memory/unique ptr">std::unique_ptr</a></span> requires that the pointed-to type is a complete type in any context where the deleter is instantiated, the special member functions must be user-declared and defined out-of-line, in the implementation file, where the implementation class is complete.
</p><p>Because when const member function calls a function through a non-const member pointer, the non-const overload of the implementation function is called, the pointer has to be wrapped in <span class="t-lc"><a href="../experimental/propagate_const.html" title="cpp/experimental/propagate const">std::experimental::propagate_const</a></span> or equivalent.
</p><p>All private data members and all private non-virtual member functions are placed in the implementation class. All public, protected, and virtual members remain in the interface class (see <a rel="nofollow" class="external text" href="http://herbsutter.com/gotw/_100/">GOTW #100</a> for the discussion of the alternatives).
</p><p>If any of the private members needs to access a public or protected member, a reference or pointer to the interface may be passed to the private function as a parameter. Alternatively, the back-reference may be maintained as part of the implementation class.
</p><p>If non-default allocators are intended to be supported for the allocation of the implementation object, any of the usual allocator awareness patterns may be utilized, including allocator template parameter defaulting to <span class="t-lc"><a href="../memory/allocator.html" title="cpp/memory/allocator">std::allocator</a></span> and constructor argument of type <a href="../memory/memory_resource.html" title="cpp/memory/memory resource"><tt>std::pmr::memory_resource*</tt></a>.
</p>
<h3><span class="mw-headline" id="Notes">Notes</span></h3>
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style=""><tr><td class="mbox-empty-cell"></td><td class="mbox-text" style="">This section is incomplete<br>Reason: note connection to value-semantic polymorphism </td></tr></table>
<h3><span class="mw-headline" id="Example">Example</span></h3>
<div class="t-example"><p>Demonstrates a pImpl with const propagation, with back-reference passed as a parameter, without allocator awareness, and move-enabled without runtime checks:</p><div class="t-example-live-link"><div class="coliru-btn coliru-btn-run-init">Run this code</div></div>
<div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="cpp source-cpp"><pre class="de1"><span class="co1">// ----------------------</span>
<span class="co1">// interface (widget.hpp)</span>
<span class="co2">#include &lt;iostream&gt;</span>
<span class="co2">#include &lt;memory&gt;</span>
<span class="co2">#include &lt;experimental/propagate_const&gt;</span>
 
<span class="kw1">class</span> widget
<span class="br0">{</span>
    <span class="kw1">class</span> impl<span class="sy4">;</span>
    <a href="../experimental/propagate_const.html"><span class="kw2427">std::<span class="me2">experimental</span><span class="sy4">::</span><span class="me2">propagate_const</span></span></a><span class="sy1">&lt;</span><a href="../memory/unique_ptr.html"><span class="kw734">std::<span class="me2">unique_ptr</span></span></a><span class="sy1">&lt;</span>impl<span class="sy1">&gt;&gt;</span> pImpl<span class="sy4">;</span>
<span class="kw1">public</span><span class="sy4">:</span>
    <span class="kw4">void</span> draw<span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span><span class="sy4">;</span> <span class="co1">// public API that will be forwarded to the implementation</span>
    <span class="kw4">void</span> draw<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
    <span class="kw4">bool</span> shown<span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="kw2">true</span><span class="sy4">;</span> <span class="br0">}</span> <span class="co1">// public API that implementation has to call</span>
 
    widget<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// even the default ctor needs to be defined in the implementation file</span>
              <span class="co1">// Note: calling draw() on default constructed object is UB</span>
    <span class="kw1">explicit</span> widget<span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span><span class="sy4">;</span>
    ~widget<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// defined in the implementation file, where impl is a complete type</span>
    widget<span class="br0">(</span>widget<span class="sy3">&amp;&amp;</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// defined in the implementation file</span>
                      <span class="co1">// Note: calling draw() on moved-from object is UB</span>
    widget<span class="br0">(</span><span class="kw4">const</span> widget<span class="sy3">&amp;</span><span class="br0">)</span> <span class="sy1">=</span> delete<span class="sy4">;</span>
    widget<span class="sy3">&amp;</span> operator<span class="sy1">=</span><span class="br0">(</span>widget<span class="sy3">&amp;&amp;</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// defined in the implementation file</span>
    widget<span class="sy3">&amp;</span> operator<span class="sy1">=</span><span class="br0">(</span><span class="kw4">const</span> widget<span class="sy3">&amp;</span><span class="br0">)</span> <span class="sy1">=</span> delete<span class="sy4">;</span>
<span class="br0">}</span><span class="sy4">;</span>
 
<span class="co1">// ---------------------------</span>
<span class="co1">// implementation (widget.cpp)</span>
<span class="co1">// #include "widget.hpp"</span>
 
<span class="kw1">class</span> widget<span class="sy4">::</span><span class="me2">impl</span>
<span class="br0">{</span>
    <span class="kw4">int</span> n<span class="sy4">;</span> <span class="co1">// private data</span>
<span class="kw1">public</span><span class="sy4">:</span>
    <span class="kw4">void</span> draw<span class="br0">(</span><span class="kw4">const</span> widget<span class="sy3">&amp;</span> w<span class="br0">)</span> <span class="kw4">const</span>
    <span class="br0">{</span>
        <span class="kw1">if</span><span class="br0">(</span>w.<span class="me1">shown</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="co1">// this call to public member function requires the back-reference </span>
            <a href="../io/cout.html"><span class="kw1762">std::<span class="me2">cout</span></span></a> <span class="sy1">&lt;&lt;</span> <span class="st0">"drawing a const widget "</span> <span class="sy1">&lt;&lt;</span> n <span class="sy1">&lt;&lt;</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
    <span class="br0">}</span>
 
    <span class="kw4">void</span> draw<span class="br0">(</span><span class="kw4">const</span> widget<span class="sy3">&amp;</span> w<span class="br0">)</span>
    <span class="br0">{</span>
        <span class="kw1">if</span><span class="br0">(</span>w.<span class="me1">shown</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span>
            <a href="../io/cout.html"><span class="kw1762">std::<span class="me2">cout</span></span></a> <span class="sy1">&lt;&lt;</span> <span class="st0">"drawing a non-const widget "</span> <span class="sy1">&lt;&lt;</span> n <span class="sy1">&lt;&lt;</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
    <span class="br0">}</span>
 
    impl<span class="br0">(</span><span class="kw4">int</span> n<span class="br0">)</span> <span class="sy4">:</span> n<span class="br0">(</span>n<span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
<span class="br0">}</span><span class="sy4">;</span>
 
<span class="kw4">void</span> widget<span class="sy4">::</span><span class="me2">draw</span><span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span> <span class="br0">{</span> pImpl<span class="sy2">-</span><span class="sy1">&gt;</span>draw<span class="br0">(</span><span class="sy2">*</span>this<span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
<span class="kw4">void</span> widget<span class="sy4">::</span><span class="me2">draw</span><span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> pImpl<span class="sy2">-</span><span class="sy1">&gt;</span>draw<span class="br0">(</span><span class="sy2">*</span>this<span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
widget<span class="sy4">::</span><span class="me2">widget</span><span class="br0">(</span><span class="br0">)</span> <span class="sy1">=</span> <span class="kw1">default</span><span class="sy4">;</span>
widget<span class="sy4">::</span><span class="me2">widget</span><span class="br0">(</span><span class="kw4">int</span> n<span class="br0">)</span> <span class="sy4">:</span> pImpl<span class="br0">{</span><a href="../memory/unique_ptr/make_unique.html"><span class="kw736">std::<span class="me2">make_unique</span></span></a><span class="sy1">&lt;</span>impl<span class="sy1">&gt;</span><span class="br0">(</span>n<span class="br0">)</span><span class="br0">}</span> <span class="br0">{</span><span class="br0">}</span>
widget<span class="sy4">::</span><span class="me2">widget</span><span class="br0">(</span>widget<span class="sy3">&amp;&amp;</span><span class="br0">)</span> <span class="sy1">=</span> <span class="kw1">default</span><span class="sy4">;</span>
widget<span class="sy4">::</span>~widget<span class="br0">(</span><span class="br0">)</span> <span class="sy1">=</span> <span class="kw1">default</span><span class="sy4">;</span>
widget<span class="sy3">&amp;</span> widget<span class="sy4">::</span><span class="me2">operator</span><span class="sy1">=</span><span class="br0">(</span>widget<span class="sy3">&amp;&amp;</span><span class="br0">)</span> <span class="sy1">=</span> <span class="kw1">default</span><span class="sy4">;</span>
 
<span class="co1">// ---------------</span>
<span class="co1">// user (main.cpp)</span>
<span class="co1">// #include "widget.hpp"</span>
 
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
<span class="br0">{</span>
    widget w<span class="br0">(</span><span class="nu0">7</span><span class="br0">)</span><span class="sy4">;</span>
    <span class="kw4">const</span> widget w2<span class="br0">(</span><span class="nu0">8</span><span class="br0">)</span><span class="sy4">;</span>
    w.<span class="me1">draw</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
    w2.<span class="me1">draw</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
<span class="br0">}</span></pre></div></div>
<p>Output:
</p>
<div dir="ltr" class="mw-geshi" style="text-align: left;"><div class="text source-text"><pre class="de1">drawing a non-const widget 7
drawing a const widget 8</pre></div></div> 
</div>
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style=""><tr><td class="mbox-empty-cell"></td><td class="mbox-text" style="">This section is incomplete<br>Reason: describe yet another alternative — "fast PImpl". The main difference is that the memory for the implementation is reserved in a data member that is an opaque C-array (inside the PImpl class definition), while in cpp file that memory is mapped (via <code>reinterpret_cast</code> or placement-<code>new</code>) to the implementation structure. This approach has it's own pros and cons, in particular, an obvious <i>pro</i> is no extra allocation, on condition that enough memory was initially reserved at <i>design-time</i> of the PImpl class. (Whereas among <i>cons</i> is reduced move-friendliness.) </td></tr></table>
<h3><span class="mw-headline" id="External_links">External links</span></h3>
<dl><dd><ul><li> ↑ <a rel="nofollow" class="external text" href="http://www.gotw.ca/gotw/028.htm">GotW #28</a> : The Fast Pimpl Idiom
</li></ul>
</dd></dl>
<ol class="references">
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="pimpl.html#cite_ref-1">↑</a></span> <span class="reference-text"><a rel="nofollow" class="external text" href="http://herbsutter.com/gotw/_100/">GotW #100</a>: Compilation Firewalls</span>
</li>
</ol>

<!-- 
NewPP limit report
Preprocessor visited node count: 2798/1000000
Preprocessor generated node count: 7924/1000000
Post‐expand include size: 116842/2097152 bytes
Template argument size: 25145/2097152 bytes
Highest expansion depth: 17/40
Expensive parser function count: 0/100
-->

<!-- Saved in parser cache with key mwiki1-mwiki_en_:pcache:idhash:14656-0!*!0!!en!*!* and timestamp 20220410082818 -->
</div>                    <!-- /bodycontent -->
                                        <!-- printfooter -->
                    <div class="printfooter">
                    Retrieved from "<a href="https://en.cppreference.com/mwiki/index.php?title=cpp/language/pimpl&amp;oldid=138246">https://en.cppreference.com/mwiki/index.php?title=cpp/language/pimpl&amp;oldid=138246</a>"                    </div>
                    <!-- /printfooter -->
                                                            <!-- catlinks -->
                    <!-- /catlinks -->
                                                            <div class="visualClear"></div>
                    <!-- debughtml -->
                                        <!-- /debughtml -->
                </div>
                <!-- /bodyContent -->
            </div>
        </div>
        <!-- /content -->
        <!-- footer -->
        <div id="cpp-footer-base" class="noprint">
            <div id="footer">
                        <div id="cpp-navigation">
            <h5>Navigation</h5>
            <ul><li><a href="https://en.cppreference.com/w/cpp/language/pimpl">Online version</a></li><li>Offline version retrieved 2022-07-30 14:05.</li></ul></div>
                        <ul id="footer-info">
                                    <li id="footer-info-lastmod"> This page was last modified on 17 February 2022, at 10:44.</li>
                                    <li id="footer-info-viewcount">This page has been accessed 365,845 times.</li>
                            </ul>
                    </div>
        </div>
        <!-- /footer -->
        <script>if(window.mw){
mw.loader.state({"site":"loading","user":"missing","user.groups":"ready"});
}</script>
<script src="../../../common/skin_scripts.js"></script>
<script>if(window.mw){
mw.loader.load(["mediawiki.action.view.postEdit","mediawiki.user","mediawiki.page.ready","mediawiki.searchSuggest","mediawiki.hidpi","ext.gadget.ColiruCompiler","ext.gadget.MathJax"], null, true);
}</script>
<script src="../../../common/site_scripts.js"></script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-2828341-1']);
_gaq.push(['_setDomainName', 'cppreference.com']);
_gaq.push(['_trackPageview']);
</script><!-- Served in 1.173 secs. -->
	</body>
<!-- Cached 20220410082818 -->
</html>